package Controladores_Jsf;

import Entidades_Persistencia.Persona;
import Entidades_Persistencia.Evaluador;
import Entidades_Persistencia.Empleado;
import Controladores_Jsf.util.JsfUtil;
import Controladores_Jsf.util.PaginationHelper;
import Entidades_Persistencia.Departamento;
import Entidades_Persistencia.NivelEstudios;
import Entidades_Persistencia.Perfil;
import Facades.PersonaFacade;
import java.util.List;

import java.io.Serializable;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;

@ManagedBean(name = "personaController")
@SessionScoped
public class PersonaController implements Serializable {

    private Persona current;
    private Evaluador entitieEvaluador=new Evaluador();
    private Empleado entitieEmpleado=new Empleado();
    private DataModel items = null;
    
    private NivelEstudios paraEditarNivelEstudios=new NivelEstudios();
    private Departamento paraEditarDepto=new Departamento();
    private Perfil paraBuscarPerfil= new Perfil();
    private  String tituloEstudios;
    private  String otrosEstudios;
    private int experienciaAnnios;
    private String cargo;
    private String nombreFind;
    private String apellidoFind;
    private int cedulaFind;
    List personas;
    private String viewSex;
    
    @EJB
    private Facades.PersonaFacade ejbFacade;
    @EJB
    private Facades.EvaluadorFacade evaluadorFacade;
    @EJB
    private Facades.EmpleadoFacade empleadoFacade;
    private PaginationHelper pagination;
    private int selectedItemIndex;

    
     private List personaEvalua;
    
        public void personaEvaluador() {
        personaEvalua=getFacade().buscarEvaluador(4);
    }
   
    public DataModel getPersonaEvalua() {
        personaEvaluador();
        items=new ListDataModel(personaEvalua);
        return items;
    }
    public PersonaController() {
    }

    public Persona getSelected() {
        if (current == null) {
            current = new Persona();
            selectedItemIndex = -1;
        }
        return current;
    }

    private PersonaFacade getFacade() {
        return ejbFacade;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return pagination;
    }

    public String prepareList() {
        recreateModel();
        return "List";
    }

    public String prepareView() {
        current = (Persona) getItems().getRowData();
        
        limpiarVariables();
        if(current.getEvaluador()!=null)
        {
            entitieEvaluador=evaluadorFacade.find(current.getCodigoInterno());
            tituloEstudios=entitieEvaluador.getTituloEstudios();
            otrosEstudios=entitieEvaluador.getOtrosEstudios();
            experienciaAnnios=entitieEvaluador.getExperienciaAnnios();
            paraEditarNivelEstudios=entitieEvaluador.getCodigoNivelEstudios();
        }
        
        if(current.getEmpleado()!=null)
        {
            entitieEmpleado=empleadoFacade.find(current.getCodigoInterno());
            cargo=entitieEmpleado.getCargo();
            paraEditarDepto=entitieEmpleado.getCodigoDepartamento();
        }
        
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public void limpiarVariables() {
        entitieEmpleado=null;
        paraEditarDepto=new Departamento();
        cargo="";
    }
    
    public String prepareCreate() {
        current = new Persona();
        selectedItemIndex = -1;
        
        limpiarVariables();
        entitieEmpleado=new Empleado();
        
        return "Create";
    }

    public String create() {
        try {
            current.setLogin(current.getCedula()+"");
//            current.setSexo((current.getSexo()+"".toUpperCase()).toCharArray()[0]);
            getFacade().create(current);
            ///
            if(current.getCodigoPerfil().getCodigo()!=1)
            {
                int id_last = current.getCodigoInterno();
                entitieEmpleado.setCodigo(id_last);
                entitieEmpleado.setCargo(cargo);
                entitieEmpleado.setPersona(current);
                empleadoFacade.create(entitieEmpleado);
            }
            ///
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("PersonaCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    
    public String prepareCreateEvaluador() {
        current = new Persona();
        selectedItemIndex = -1;
        
        entitieEvaluador=null;
        paraBuscarPerfil=new Perfil();
        tituloEstudios="";
        otrosEstudios="";
        experienciaAnnios=0;
        paraEditarNivelEstudios=null;
        paraEditarNivelEstudios=new NivelEstudios();
        limpiarVariables();
        
        return "Create";
    }
    
      public String createEvaluador() {
         try {
                current.setLogin(current.getCedula()+"");
                current.setCodigoPerfil(paraBuscarPerfil);
                current.setEmpleado(null);
                getFacade().create(current);
                
                ///
                entitieEvaluador=new Evaluador();
                int id_last = current.getCodigoInterno();
                entitieEvaluador.setCodigo(id_last);
                entitieEvaluador.setTituloEstudios(tituloEstudios);
                entitieEvaluador.setOtrosEstudios(otrosEstudios);
                entitieEvaluador.setExperienciaAnnios(experienciaAnnios);
                entitieEvaluador.setCodigoNivelEstudios(paraEditarNivelEstudios);
                entitieEvaluador.setPersona(current);
                evaluadorFacade.create(entitieEvaluador);
           
            ///
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("PersonaCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String prepareEdit() {
        current = (Persona) getItems().getRowData();
        
        entitieEvaluador=null;
        tituloEstudios="";
        otrosEstudios="";
        experienciaAnnios=0;
        paraEditarNivelEstudios=null;
        paraEditarNivelEstudios=new NivelEstudios();
        limpiarVariables();
        
        if(current.getEmpleado()!=null)
        {
            entitieEmpleado=empleadoFacade.find(current.getCodigoInterno());
            cargo=entitieEmpleado.getCargo();
            paraEditarDepto=entitieEmpleado.getCodigoDepartamento();
        }
        if(current.getEvaluador()!=null)
        {
            entitieEvaluador=evaluadorFacade.find(current.getCodigoInterno());
            tituloEstudios=entitieEvaluador.getTituloEstudios();
            otrosEstudios=entitieEvaluador.getOtrosEstudios();
            experienciaAnnios=entitieEvaluador.getExperienciaAnnios();
            paraEditarNivelEstudios=entitieEvaluador.getCodigoNivelEstudios();
        }
        
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Edit";
    }

    public String updateEvaluador() {
        try 
        {
             entitieEvaluador.setCodigoNivelEstudios(paraEditarNivelEstudios);
             entitieEvaluador.setTituloEstudios(tituloEstudios);
             entitieEvaluador.setOtrosEstudios(otrosEstudios);
             entitieEvaluador.setExperienciaAnnios(experienciaAnnios);
             evaluadorFacade.edit(entitieEvaluador);
             current.setEvaluador(entitieEvaluador);
             getFacade().edit(current);
             JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("EvaluadorUpdated"));
             return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    public String update() {
        try 
        {
            if(current.getCodigoPerfil().getCodigo()!=1)
            {
                entitieEmpleado.setCargo(cargo);
                entitieEmpleado.setCodigoDepartamento(paraEditarDepto);
                empleadoFacade.edit(entitieEmpleado);
                current.setEmpleado(entitieEmpleado);
            }
            
            if(current.getCodigoPerfil().getCodigo()==1 && entitieEmpleado!=null) {
                if(!entitieEmpleado.getProyectoList().isEmpty())
                {
                    JsfUtil.addErrorMessage("El empleado no puede cambiar a ser administrador, porque tiene proyectos relacionados");
                    return null;
                }
                else
                {
                    empleadoFacade.remove(entitieEmpleado);
                    current.setEmpleado(null);
                }
            }
            getFacade().edit(current);
            
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("PersonaUpdated"));
            return "View";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String destroy() {
        current = (Persona) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        
        limpiarVariables();
        if(current.getEmpleado()!=null)
        {
            entitieEmpleado=empleadoFacade.find(current.getCodigoInterno());
            cargo=entitieEmpleado.getCargo();
            paraEditarDepto=entitieEmpleado.getCodigoDepartamento();
        }
        if(current.getEvaluador()!=null)
        {
            entitieEvaluador=evaluadorFacade.find(current.getCodigoInterno());
            tituloEstudios=entitieEvaluador.getTituloEstudios();
            otrosEstudios=entitieEvaluador.getOtrosEstudios();
            experienciaAnnios=entitieEvaluador.getExperienciaAnnios();
            paraEditarNivelEstudios=entitieEvaluador.getCodigoNivelEstudios();
        }
        
        performDestroy();
        recreateModel();
        return "List";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            
            if(entitieEmpleado!=null)
            {
                if(!entitieEmpleado.getProyectoList().isEmpty())
                {
                    JsfUtil.addErrorMessage("El empleado no puede ser eliminado, porque tiene proyectos relacionados");
                    return;
                }
                else
                {
                    empleadoFacade.remove(entitieEmpleado);
                    getFacade().remove(current);
                }
            }
            
            if(entitieEvaluador != null)
            {
                if(!entitieEvaluador.getEvaluacionProyectoList().isEmpty())
                {
                    JsfUtil.addErrorMessage("El evaluador no puede ser eliminado, porque tiene proyectos relacionados");
                    return;
                }
                else
                {
                    evaluadorFacade.remove(entitieEvaluador);
                    getFacade().remove(current);
                }
            }
            
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("PersonaDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count - 1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }

    private void recreateModel() {
        items = null;
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    @FacesConverter(forClass = Persona.class)
    public static class PersonaControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            PersonaController controller = (PersonaController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "personaController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Persona) {
                Persona o = (Persona) object;
                return getStringKey(o.getCodigoInterno());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + PersonaController.class.getName());
            }
        }
    }
    
    public String prepareFind(){
        nombreFind="";
        apellidoFind="";
        cedulaFind=0;
        paraBuscarPerfil=new Perfil();
        return "Buscar";
    }
    
    public String findPersona(){
        if(paraBuscarPerfil==null)personas=getFacade().findByParams(nombreFind, apellidoFind, cedulaFind, 0);
        else personas=getFacade().findByParams(nombreFind, apellidoFind, cedulaFind, paraBuscarPerfil.getCodigo());
        return "Result";
    }

    public String getCargo() {
        return cargo;
    }

    public void setCargo(String cargo) {
        this.cargo = cargo;
    }

    public Empleado getEntitieEmpleado() {
        return entitieEmpleado;
    }

    public void setEntitieEmpleado(Empleado entitieEmpleado) {
        this.entitieEmpleado = entitieEmpleado;
    }

    public Departamento getParaEditarDepto() {
        return paraEditarDepto;
    }

    public void setParaEditarDepto(Departamento paraEditarDepto) {
        this.paraEditarDepto = paraEditarDepto;
    }

    public String getApellidoFind() {
        return apellidoFind;
    }

    public void setApellidoFind(String apellidoFind) {
        this.apellidoFind = apellidoFind;
    }

    public int getCedulaFind() {
        return cedulaFind;
    }

    public void setCedulaFind(int cedulaFind) {
        this.cedulaFind = cedulaFind;
    }

    public String getNombreFind() {
        return nombreFind;
    }

    public void setNombreFind(String nombreFind) {
        this.nombreFind = nombreFind;
    }

    public Perfil getParaBuscarPerfil() {
        return paraBuscarPerfil;
    }

    public void setParaBuscarPerfil(Perfil paraBuscarPerfil) {
        this.paraBuscarPerfil = paraBuscarPerfil;
    }

    public DataModel getPersonas() {
        items=new ListDataModel(personas);
        return items;
    }

    public void setPersonas(List personas) {
        this.personas = personas;
    }

    public String getViewSex() {
        if(current.getSexo()=='F') return "Femenino";
        else return "Masculino";
    }

    public void setViewSex(String viewSex) {
        this.viewSex = viewSex;
    }

    public int getExperienciaAnnios() {
        return experienciaAnnios;
    }

    public String getOtrosEstudios() {
        return otrosEstudios;
    }

    public NivelEstudios getParaEditarNivelEstudios() {
        return paraEditarNivelEstudios;
    }

    public String getTituloEstudios() {
        return tituloEstudios;
    }

    public void setTituloEstudios(String tituloEstudios) {
        this.tituloEstudios = tituloEstudios;
    }

    public void setOtrosEstudios(String otrosEstudios) {
        this.otrosEstudios = otrosEstudios;
    }

    public void setExperienciaAnnios(int experienciaAnnios) {
        this.experienciaAnnios = experienciaAnnios;
    }

    public void setParaEditarNivelEstudios(NivelEstudios paraEditarNivelEstudios) {
        this.paraEditarNivelEstudios = paraEditarNivelEstudios;
    }

    public void setEntitieEvaluador(Evaluador entitieEvaluador) {
        this.entitieEvaluador = entitieEvaluador;
    }

    public Evaluador getEntitieEvaluador() {
        return entitieEvaluador;
    }
    
}